package org.example.zuoye.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.example.zuoye.entity.Appoint;
import org.example.zuoye.entity.Doctor;
import org.example.zuoye.entity.Patient;
import org.example.zuoye.entity.Schedules;
import org.example.zuoye.mapper.AppointMapper;
import org.example.zuoye.mapper.DoctorMapper;
import org.example.zuoye.mapper.PatientMapper;
import org.example.zuoye.mapper.SchedulesMapper;
import org.example.zuoye.service.AppointService;
import org.example.zuoye.service.PatientService;
import org.example.zuoye.vo.AppointInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;


/**
 * @Author xinchen
 * @Date: 2024/08/15/ 11:49
 * @Description
 */
@Service
@Slf4j
public class AppointServiceImpl implements AppointService {

    @Autowired
    private AppointMapper appointMapper;

    @Autowired
    private SchedulesMapper scheduleMapper;

    @Autowired
    private PatientMapper patientMapper;


    @Override
    public PageInfo search(Integer page, Integer limit, Appoint appoint) {
        try(Page<?> __ = PageHelper.startPage(page, limit)) {
            return new PageInfo<>(appointMapper.selectByPrimaryKey(appoint));
        }
    }


    @Override
    public int remove(Integer[] ids) {
        return 0;
    }

    @Override
    public int add(Appoint appoint) throws Exception {

        // 获取当前时间
        Date currentTime = new Date();
        appoint.setAppointTime(currentTime);
        appoint.setStatus("待叫号");

        return appointMapper.insert(appoint);
    }

    @Override
    public int update(Appoint appoint) throws Exception {
        return 0;
    }

    // 修改业务
    @Override
    public int edit(Appoint appoint) {
        // 业务判断部分

        return appointMapper.updateByPrimaryKeySelective(appoint);
    }
    // 叫号
    @Override
    public boolean editById(Integer[] ids) throws Exception {
        // 只修改的状态
        List<Appoint> list = appointMapper.findByids(ids);
        if(list != null && ! list.isEmpty()){
            // 遍历列表，检查状态并更新
            for (Appoint appoint : list) {
                if (!"待叫号".equals(appoint.getStatus())) {
                    throw new Exception("该用户已叫号");
                }else{
                    // 患者表
                    if(ObjectUtils.isEmpty(appoint.getPatId())){
                        throw new Exception("患者信息不存在");
                    }
                    Patient patient = patientMapper.selectByPrimaryKey(Long.valueOf(appoint.getPatId()));
                    // 放号表
                    if(ObjectUtils.isEmpty(appoint.getScheduleId())){
                        throw new Exception("放号信息不存在");
                    }
                    Schedules schedule = scheduleMapper.selectByPrimaryKey(Long.valueOf(appoint.getScheduleId()));
                    if(ObjectUtils.isEmpty(schedule)){
                        throw new Exception("放号信息不存在");
                    }
                    Date startTime = schedule.getStartTime();
                    Date endTime = schedule.getEndTime();
                    // 当前时间
                    Date currentTime = new Date();
                    if(currentTime.before(startTime) || currentTime.after(endTime)){
                        throw new Exception("当前时间不在放号时间段内");
                    }
                    if(schedule.getAvailableSlots() > 0){
                        schedule.setAvailableSlots(schedule.getAvailableSlots() - 1);
                        scheduleMapper.updateByPrimaryKeySelective(schedule);
                    }
                    // 患者检查余额
                    double money =patient.getPrice() - appoint.getMoney();
                    if(money < 0){
                        throw new Exception("余额不足");
                    }else{
                        patient.setPrice(money);
                        patientMapper.updateByPrimaryKeySelective(patient);
                        appoint.setStatus("已叫号");
                        appointMapper.updateByPrimaryKeySelective(appoint);
                    }
                }
            }
        }
        return true;
    }

    /**
     * 返回放好表
     * @param sid
     * @return
     */
    @Override
    public List<Appoint> getBySid(Integer sid) {
        return  appointMapper.selectByScheduleId(Long.valueOf(sid));
    }

    /**
     * 取消预约情况
     * @param id
     * @return
     */
    @Override
    public boolean updateById(Integer id) throws Exception{
        // 查询
        Appoint appoint = appointMapper.select(Long.valueOf(id));
        if(ObjectUtils.isEmpty(appoint.getPatId())){
            throw new Exception("患者信息不存在");
        }
        Patient patient = patientMapper.selectByPrimaryKey(Long.valueOf(appoint.getPatId()));
        if(ObjectUtils.isEmpty(appoint.getScheduleId())){
            throw new Exception("放号信息不存在");
        }
        Schedules schedules =  scheduleMapper.selectByPrimaryKey(Long.valueOf(appoint.getScheduleId()));
        // 业务判断
        // 更新患者表的金额
        double money =patient.getPrice() + appoint.getMoney();
        patient.setPrice(money);
        // 更新放号表
        if(ObjectUtils.isEmpty(schedules)){
            throw new Exception("放号信息不存在");
        }
        if(schedules.getAvailableSlots() > 0){
            schedules.setAvailableSlots(schedules.getAvailableSlots() + 1);
            scheduleMapper.updateByPrimaryKeySelective(schedules);
            // 更新预约表
            patientMapper.updateByPrimaryKeySelective(patient);
            appoint.setStatus("待叫号");
            appointMapper.updateByPrimaryKeySelective(appoint);
        }
        return true;
    }

    /**
     * 删除操作
     * @param id
     * @return
     */
    @Override
    public int removeById(Integer id) {
        return appointMapper.deleteByPrimaryKey(Long.valueOf(id));
    }

    /**
     * 修改状态为已完成
     * @param appoint
     * @return
     */
    @Override
    public int updateByStatue(Appoint appoint) throws Exception{
        if(appoint.getStatus().equals("已叫号")){
            appoint.setStatus("已完成");
            return appointMapper.updateByPrimaryKeySelective(appoint);
        }else {
            throw new Exception("请先叫号");
        }
    }

    /**
     * 给用户添加病例
     */
    @Override
    public int updateByRemark(Appoint appoint) throws Exception{
        Appoint sappoint = appointMapper.select(Long.valueOf(appoint.getAppId()));
        if(sappoint.getStatus().equals("已完成")){
            sappoint.setRemark(appoint.getRemark());
            return appointMapper.updateByPrimaryKeySelective(sappoint);
        }else {
            throw new RuntimeException("请先完成预约");
        }
    }


    /**
     * 给用户添加预约信息
     * @param appoint
     * @return
     */
    @Override
    public int save(Appoint appoint) throws Exception {
        // 获取当前时间
        Date currentTime = new Date();
        appoint.setAppointTime(currentTime);
        appoint.setStatus("待叫号");
        appoint.setMoney(20.0);
        // 患者扣除费用
        if(appoint.getPatient().getPrice()< 20.0){
            throw new RuntimeException("患者余额不足");
        }
        // 扣除费用
        appoint.getPatient().setPrice(appoint.getPatient().getPrice() - 20.0);

        // 剩余号源头-1
        if(appoint.getSchedules().getAvailableSlots() > 0){
            appoint.getSchedules().setAvailableSlots(appoint.getSchedules().getAvailableSlots() - 1);
        }else {
            throw new RuntimeException("已无号源");
        }
        patientMapper.updateByPrimaryKeySelective(appoint.getPatient());
        scheduleMapper.updateByPrimaryKeySelective(appoint.getSchedules());

        return appointMapper.save(appoint);
    }

    /**
     * 根据病人id，查询所有的预约信息
     * @param patId
     * @return
     */
    @Override
    public List<AppointInfo> getByPatId(Integer patId,String date) throws Exception {

        List<AppointInfo> appointments = null;

        if(date == null || date.equals("all")){
            return appointMapper.getByPatId(patId);
        }else if (date.equals("week")) {
            // 假设 date 字段是一个 Date 对象，您需要根据当前日期减去 7 天来获取一周前的日期
            Date weekAgo = new Date(System.currentTimeMillis() - 7 * 24 * 60 * 60 * 1000);
            appointments = appointMapper.getByPatIdAndDate(patId, weekAgo);
        } else if (date.equals("month")) {
            // 假设 date 字段是一个 Date 对象，您需要根据当前日期减去 30 天来获取一个月前的日期
            Date monthAgo = new Date(System.currentTimeMillis() - 30 * 24 * 60 * 60 * 1000);
            appointments = appointMapper.getByPatIdAndDate(patId, monthAgo);
        } else if (date.equals("halfYear")) {
            // 假设 date 字段是一个 Date 对象，您需要根据当前日期减去 180 天来获取半年前的日期
            Date halfYearAgo = new Date(System.currentTimeMillis() - 180 * 24 * 60 * 60 * 1000);
            appointments = appointMapper.getByPatIdAndDate(patId, halfYearAgo);
        }
        if(ObjectUtils.isEmpty(appointments)){
            throw new RuntimeException("当前无预约信息");
        }
        return appointments;
    }

    /**
     * 用户取消预约业务
     * @param appId
     * @return
     */
    @Override
    public boolean updateByAppId(Integer appId) throws Exception{
        // 改变预约状态
        Appoint app = appointMapper.select(Long.valueOf(appId));
        app.setStatus("已取消");

        /**
         * 放号 + 1
         */
        Schedules schedules = scheduleMapper.selectByPrimaryKey(Long.valueOf(app.getScheduleId()));
        if(ObjectUtils.isEmpty(schedules)){
            throw new RuntimeException("放号信息不存在");
        }
        schedules.setAvailableSlots(schedules.getAvailableSlots() + 1);

        /**
         * 用户扣钱+回来
         */
        Patient patient = patientMapper.selectByPrimaryKey(Long.valueOf(app.getPatId()));
        patient.setPrice(patient.getPrice() + app.getMoney());
        if(ObjectUtils.isEmpty(patient)){
            throw new RuntimeException("患者信息不存在");
        }
        // 更新三个表中的数据
        patientMapper.updateByPrimaryKeySelective(patient);
        // 更新放号表
        scheduleMapper.updateByPrimaryKeySelective(schedules);
        // 更新预约表
        appointMapper.updateByPrimaryKeySelective(app);

        if(appointMapper.updateByPrimaryKeySelective(app) > 0){
            return true;
        }else {
            return false;
        }
    }


}
